package net.animats.music;

import java.util.Map;
import java.util.HashMap;
import java.util.List;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;

public class ChordType extends IntervalSet {

    private static Map<String, ChordType> chordTypes = new HashMap<String, ChordType>();

    // CREATE ALL THE KNOWN ChordType INSTANCES
    static {
        chordTypes.put("Major", new ChordType("Major", "", 0, 4, 7));
        chordTypes.put("Augmented", new ChordType("Augmented", "aug", 0, 4, 8));
        chordTypes.put("Minor", new ChordType("Minor", "m", 0, 3, 7));
        chordTypes.put("Diminished", new ChordType("Diminished", "dim", 0, 3, 6));
        chordTypes.put("7th", new ChordType("7th", "7", 0, 4, 7, 10));
        chordTypes.put("Major7th", new ChordType("Major7th", "Maj7", 0, 4, 7, 11));
        chordTypes.put("Minor7th", new ChordType("Minor7th", "m7", 0, 3, 7, 10));
        chordTypes.put("Major9th", new ChordType("Major9th", "Maj9", 0, 4, 7, 11, 15));
    }

    private ChordType(String _name, String _shortName, Integer... _intervals) {
        super(_name, _shortName, _intervals);
    }

    public static Object[] getChordTypeNamesArray() {
        Object[] newArray = chordTypes.keySet().toArray().clone();
        Arrays.sort(newArray);
        return newArray;
    }

    public static List getChordTypeNames() {
        return new ArrayList<String>(chordTypes.keySet());
    }

    public static ChordType getChordType(String _name) {
        return chordTypes.get(_name);
    }

    public static ChordType getChordType(NoteSet _noteSet) {
       return getChordType (_noteSet.getIntervalSet());
    }

    public static ChordType getChordType(IntervalSet _intervalSet) {
        // FOR NOW THIS PRESUMES THE FIRST NOTE IS THE ROOT NOTE
        // EVENTUALLY CYCLE THROUGH ALL NOTES AS THE ROOT NOTE
        // WHEN SEARCHING
        Collection allChordTypes = chordTypes.values();

        for (Object currentChordType : allChordTypes) {
            if (currentChordType.equals(_intervalSet)) {
                //_intervalSet.setName(((IntervalSet) currentChordType).getName());
                //_intervalSet.setShortName(((IntervalSet) currentChordType).getShortName());
                return (ChordType) currentChordType;
            }
        }

        // The IntervalSet IS NOT A KNOWN CHORD
        //_intervalSet.setName("Unknown");
        //_intervalSet.setShortName("Unk");

        return null;
    }

    public static Collection<ChordType> getChordTypes() {
        return chordTypes.values();
    }
}
